//
//  OrgBean.swift
//  test-ios
//
//  Created by wyz5204 on 2023/6/5.
//

import Foundation
import GRDB


// MARK: - OrgBean
struct OrgBean: Codable {
    var _id : Int64 = -1
    let id, orgCode: Int
    let orgName: String
    let description: JSONNull?
    let nowNum, totalNum, totalSpace, nowSpace: Int
    let orgType, verInfo: Int
    let version, delFlag: JSONNull?
    let expirationTime: String?
    let createTime, updateTime, createBy, updateBy: JSONNull?
    let owner: String
    let ifExpiration, stockCode: JSONNull?
    let initByOrgType: Bool
    let orgTypeName, password, ownerName, isOrgCreate: JSONNull?
    let payMode, payChannel: JSONNull?
    let newMsg: Bool
    let userID: Int
    let label, datumPrefix: JSONNull?
    let spaceButton: Bool
    let insideFlag: JSONNull?
    let orgNote: String
    let orgNameNote: JSONNull?
    
    enum CodingKeys: String, CodingKey {
        case id, orgCode, orgName, description, nowNum, totalNum, totalSpace, nowSpace, orgType, verInfo, version, delFlag, expirationTime, createTime, updateTime, createBy, updateBy, owner, ifExpiration, stockCode, initByOrgType, orgTypeName, password, ownerName, isOrgCreate, payMode, payChannel, newMsg
        case userID = "userId"
        case label
        case datumPrefix = "prefix"
        case spaceButton, insideFlag, orgNote, orgNameNote
    }
}

// MARK: OrgBean convenience initializers and mutators

extension OrgBean {
    init(data: Data) throws {
        self = try newJSONDecoder().decode(OrgBean.self, from: data)
    }
    
    init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }
    
    init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }
    
    func with(
        id: Int? = nil,
        orgCode: Int? = nil,
        orgName: String? = nil,
        description: JSONNull?? = nil,
        nowNum: Int? = nil,
        totalNum: Int? = nil,
        totalSpace: Int? = nil,
        nowSpace: Int? = nil,
        orgType: Int? = nil,
        verInfo: Int? = nil,
        version: JSONNull?? = nil,
        delFlag: JSONNull?? = nil,
        expirationTime: String?? = nil,
        createTime: JSONNull?? = nil,
        updateTime: JSONNull?? = nil,
        createBy: JSONNull?? = nil,
        updateBy: JSONNull?? = nil,
        owner: String? = nil,
        ifExpiration: JSONNull?? = nil,
        stockCode: JSONNull?? = nil,
        initByOrgType: Bool? = nil,
        orgTypeName: JSONNull?? = nil,
        password: JSONNull?? = nil,
        ownerName: JSONNull?? = nil,
        isOrgCreate: JSONNull?? = nil,
        payMode: JSONNull?? = nil,
        payChannel: JSONNull?? = nil,
        newMsg: Bool? = nil,
        userID: Int? = nil,
        label: JSONNull?? = nil,
        datumPrefix: JSONNull?? = nil,
        spaceButton: Bool? = nil,
        insideFlag: JSONNull?? = nil,
        orgNote: String? = nil,
        orgNameNote: JSONNull?? = nil
    ) -> OrgBean {
        return OrgBean(
            id: id ?? self.id,
            orgCode: orgCode ?? self.orgCode,
            orgName: orgName ?? self.orgName,
            description: description ?? self.description,
            nowNum: nowNum ?? self.nowNum,
            totalNum: totalNum ?? self.totalNum,
            totalSpace: totalSpace ?? self.totalSpace,
            nowSpace: nowSpace ?? self.nowSpace,
            orgType: orgType ?? self.orgType,
            verInfo: verInfo ?? self.verInfo,
            version: version ?? self.version,
            delFlag: delFlag ?? self.delFlag,
            expirationTime: expirationTime ?? self.expirationTime,
            createTime: createTime ?? self.createTime,
            updateTime: updateTime ?? self.updateTime,
            createBy: createBy ?? self.createBy,
            updateBy: updateBy ?? self.updateBy,
            owner: owner ?? self.owner,
            ifExpiration: ifExpiration ?? self.ifExpiration,
            stockCode: stockCode ?? self.stockCode,
            initByOrgType: initByOrgType ?? self.initByOrgType,
            orgTypeName: orgTypeName ?? self.orgTypeName,
            password: password ?? self.password,
            ownerName: ownerName ?? self.ownerName,
            isOrgCreate: isOrgCreate ?? self.isOrgCreate,
            payMode: payMode ?? self.payMode,
            payChannel: payChannel ?? self.payChannel,
            newMsg: newMsg ?? self.newMsg,
            userID: userID ?? self.userID,
            label: label ?? self.label,
            datumPrefix: datumPrefix ?? self.datumPrefix,
            spaceButton: spaceButton ?? self.spaceButton,
            insideFlag: insideFlag ?? self.insideFlag,
            orgNote: orgNote ?? self.orgNote,
            orgNameNote: orgNameNote ?? self.orgNameNote
        )
    }
    
    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }
    
    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}

// GRDB 数据库的开发
extension OrgBean : RDEntity {
    
    // 数据库的创建
    static let databaseTableName    = "table_org_bean"
    static let _id                  = DBColumn("_id")
    static let owner                = DBColumn("owner")
    static let orgName              = DBColumn("orgName")
    static let id                   = DBColumn("id")
    static let orgCode              = DBColumn("orgCode")
    
    
    mutating func didInsert(with rowID: Int64, for column: String?) {
        self._id = rowID
    }
    
    func encode(to container: inout PersistenceContainer) {
        container["owner"] = owner
        container["orgName"] = orgName
        container["id"] = id
        container["orgCode"] = orgCode
    }
    
    init(row: Row) {
        _id         = row["_id"]
        owner       = row["owner"]
        orgName     = row["orgName"]
        id          = row["id"]
        orgCode     = row["orgCode"]
        
        description = nil
        nowNum = 0
        totalNum =  0
        totalSpace =  0
        nowSpace =  0
        orgType =  0
        verInfo = 0
        version = nil
        delFlag = nil
        expirationTime = nil
        createTime = nil
        updateTime = nil
        createBy = nil
        updateBy = nil
        ifExpiration = nil
        stockCode = nil
        initByOrgType =  false
        orgTypeName = nil
        password = nil
        ownerName = nil
        isOrgCreate = nil
        payMode = nil
        payChannel = nil
        newMsg = false
        userID = 0
        label = nil
        datumPrefix = nil
        spaceButton = false
        insideFlag = nil
        orgNote = ""
        orgNameNote = nil
    }
}

